/*
* Copyright 2011 Pavel Kozhin 
*
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed  under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License.
*
* Author: Pavel Kozhin.
*/
package org.etherframework.core
{
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	
	import mx.core.IMXMLObject;
	import mx.core.Singleton;
	
	import org.etherframework.common.IStatefulDestroyable;
	import org.etherframework.core.manager.IEtherManager;
	
	public class ModuleStarter implements IMXMLObject
	{
		private var _id:String;
		private var _document:Object;
		private var _module:Class;
		private var _moduleInstance:IModule;
		private var _dispatcher:IEventDispatcher;
		private var _isReady:Boolean = false;
		private var _isStarted:Boolean = false;
		private var _domain:String;
		private var _access:String;
		
		public function initialized(document:Object, id:String):void
		{
			_id = id;
			_document = document;
			_dispatcher = IEventDispatcher(document);
			_dispatcher.addEventListener(Event.ADDED, addedHandler);
		}
		
		private function addedHandler(event:Event):void
		{
			_dispatcher.removeEventListener(Event.ADDED, addedHandler);
			_dispatcher.addEventListener(Event.REMOVED_FROM_STAGE, removedHandler);
			
			_isReady = true;
			start();
		}
		
		private function removedHandler(event:Event):void
		{
			IEtherManager(Singleton.getInstance("org.etherframework.core.manager::IEtherManager"))
				.destroy(_moduleInstance);
				
			_dispatcher.removeEventListener(Event.REMOVED_FROM_STAGE, removedHandler);
			_dispatcher.addEventListener(Event.ADDED, addedHandler);
		}
		
		private function start():void
		{
			if (_isReady && _module)
			{
				if (!_moduleInstance)
				{
					_moduleInstance = new _module(_dispatcher); 
					_moduleInstance.access = _access;
					_moduleInstance.domain = _domain;
				}
				
				if (_moduleInstance is IStatefulDestroyable && 
					IStatefulDestroyable(_moduleInstance).destroyed)
				{
					_dispatcher.removeEventListener(Event.ADDED, addedHandler);
					_dispatcher.removeEventListener(Event.REMOVED_FROM_STAGE, removedHandler);
					return;
				}
				
				var manager:IEtherManager;
				try {
					manager = IEtherManager(Singleton.getInstance(
						"org.etherframework.core.manager::IEtherManager"));
				} catch (e:Error) {
					throw new Error("Please, make sure that you have EtherConfig initialized.");
				}
				manager.attach(_moduleInstance);
				
				if (!_isStarted)
				{
					_moduleInstance.start();
					_moduleInstance.started = true;
				}
				
				_isStarted = true;
			}
		}
		
		/**
		 * A module class which extends org.etherframework.core.Module.
		 */
		public function get module():Class { return _module; }
		public function set module(value:Class):void 
		{ 
			if (!_module)
			{
				_module = value;
				start();
			}
		}
		
		[Inspectable(enumeration="single,multiple")]
		public function get domain():String { return _domain; }
		public function set domain(value:String):void 
		{
			_domain = value;
			
			if (_moduleInstance)
				_moduleInstance.domain = _domain;
		}
		
		[Inspectable(enumeration="local,hierarchical,global")]
		public function get access():String { return _access; }
		public function set access(value:String):void 
		{
			_access = value;
			
			if (_moduleInstance)
				_moduleInstance.access = _access;
		}
	}
}